搭建 Hadoop 分布式
准备机器
克隆两个虚拟机,修改主机名和网络,分别如下
1 | hadoop10 192.168.1.10 |
因为是克隆的虚拟机,所以 java 环境,rexyan 用户在伪分布式都有了,所以这些步骤就不重复了。hadoop 因为之前进行了配置,所以会重装。三个虚拟机,要求每个内存至少 4G,且都选择了时区和进行时间的同步,
因为台机器会互相拷贝和传输文件,所以需要开启免密登录,这里以 192.168.1.10 为主要的机器,他会往 192.168.1.11 和 192.168.1.12 拷贝文件,所以配置 192.168.1.10 在 192.168.1.11 和 192.168.1.12 的免密登录。在 192.168.1.10 上执行
1 | ssh-keygen -t rsa # 生成 192.168.1.10 的密钥信息 |
编写集群文件分发脚本
1 | !/bin/bash |
例如,需要在 hadoop10 tmp 目录下创建 test 文件,并将文件分发到 hadoop11,hadoop12 中的 tmp 目录下
这样就能将 10 下面的 /tmp/test 文件拷贝到 11 和 12 下面
规划集群
重新规划集群角色如下:
1 | hadoop10 hadoop11 hadoop12 |
安装 Hadoop
解压上传好的 hadoop 到 /opt/module/
1 | tar -zxvf /opt/soft/hadoop-2.7.2.tar.gz -C /opt/module/ |
配置 core-site.xml 将 hdfs 配置成为分布式,因为规划的是在 10上启动 namenode,所以配置文件中 value为 10的地址
1 | <configuration> |
在 hdfs-site.xml 中配置 2NN(SecondaryNamenode),按照规划 2NN 是配置到 hadoop12 机器上的,所以 value 要写 hadoop12 的地址。
1 | <configuration> |
配置 yarn-site.xml,按照规划 ResourceManager 运行在 hadoop11,所以 value 指定 ResourceManager 运行的机器为 hadoop11
1 | <configuration> |
将 mapred-site.xml.template 文件复制另一份为 mapred-site.xml,并在其中设置 mapreduce 的运行方式为 yarn
1 | <configuration> |
利用集群分发脚本,将配置好的 hadoop 文件分发到其他机器
1 | bash xsync /opt/module/hadoop-2.7.2/ |
分别配置三台机器的环境变量,将 hadoop 加入到坏境变量中,如果没有配置 java 的环境变量,也需要进行配置
1 | JAVA_HOME=/opt/module/jdk1.8.0_121 |
使用 SSH 执行在远端执行命令及问题
在 10 机器上,执行 ssh hadoop11 jps,提示 找不到 jps 命令,但是 hadoop11 的确已经配置了 java 的环境变量了的。
1 | [rexyan@hadoop10 ~]$ ssh hadoop11 jps |
为什么会发生这种现象呢,因为 ssh 一台机器后马上执行某命令,这样的没有交互的登录方式叫做 Non-Login shell,这种 Non-Login shell 执行登录脚本的顺序是
1 | 1. ~/.bashrc |
因为我们的环境变量是添加到 /etc/profile 下面的,没有在 Non-Login shell 的加载顺序中,所以提示找不到 jps 命令。解决方法就是在 /etc/bashrc 中 source /etc/profile。这样就算是以 Non-Login shell 的方式执行命令,那么也能找到 /etc/profile 下设置的环境变量,也就能找到 jps 命令。
所以我们需要在所有机器的 /etc/bashrc 中添加 source /etc/profile
编写集群执行同一命令脚本
1 | !/bin/bash |
例如,在所有机器上执行 ifconfig,只需执行 bash xcall ifconfig 即可
1 | bash xcall ifconfig |
启动 HDFS
在启动 hdfs 之前,我们需要对 namenode 进行格式化,因为 namenode 是在 hadoop10 机器上的,所以需要在 hadoop10 机器上执行
1 | hadoop namenode -format |
在 hadoop10 上启动 namenode
1 | hadoop-daemon.sh start namenode |
在 hadoop10,hadoop11,hadoop12 上启动 datanode
1 | bash xcall hadoop-daemon.sh start datanode |
在 hadoop12 上启动 SecondaryNamenode
1 | hadoop-daemon.sh start secondarynamenode |
查看各机器启动状态
1 | bash xcall jps |
访问 web 页面看是成功,因为 namenode 是在 10 上的,所以访问 http://192.168.1.10:50070/ 即可
启动 YARN
ResourceManager 是规划在 hadoop11 机器上的,所以在 hadoop11 启动 ResourceManager
1 | yarn-daemon.sh start resourcemanager |
在 hadoop10,hadoop11,hadoop12 上启动 nodemanager
1 | bash xcall yarn-daemon.sh start nodemanager |
访问 web 页面看是否存在文件,resourcemanager 是在 hadoop11 上启动的,所以访问 http://192.168.1.11:8088/cluster ,可以看到三个 nodemanager 也启动了。
测试集群
创建一个文件夹,上传一个文件到创建好的 hdfs 文件夹中
1 | hadoop fs -mkdir /wcinput3 |
测试 yarn,并查询运行结果
1 | hadoop jar hadoop-mapreduce-examples-2.7.2.jar wordcount /wcinput3 /wcoutput3 |
群启脚本
在 /opt/module/hadoop-2.7.2/sbin 目录下有很多启动和停止的脚本,可以不用一个一个去执行和停止 hdfs 进程和 yarn 进程,群启脚本可以批量启动和停止。
群起脚本的原理是获取集群中所有的节点的主机名,默认读取当前机器 HADOOP_HOME/etc/hadoop/slaves,获取集群中所有的节点的主机名。循环执行 ssh 主机名 hadoop-daemon.sh start xxx 所以需要保证当前机器(需要执行群启的机器)到其他节点,已经配置了ssh免密登录,保证集群中所有机器当前用户的家目录/.bashrc中,已经配置 source /etc/profile。
注意⚠️:start-all.sh 时,其实分别调用了start-dfs.sh 和 start-yarn.sh,start-dfs.sh 可以在集群的任意一台机器使用!可以启动 HDFS 中的所有进程。start-yarn.sh 在集群的非RM所在的机器使用,不会启动resourcemanager, stop-yarn.sh 也是一样的,不会停止 resourcemanager 。所以,建议是配置 RM 所在机器到其他机器的 SSH 免密登录,都在 RM 所在的机器执行群起和群停脚本 xsync 和 xcall 只放在 RM 所在的机器即可(上面我们不是这样的,上面我们的规划是 11 是 RM 所在的机器,但是 10 配置了到所有机器的免密登录,xsync 和 xcall 脚本)
在 10 上配置 slaves 文件
1 | hadoop10 |
停止所有服务,然后查看状态
1 | stop-all.sh |
群启 hdfs
群启 yarn
单独在 11 上启动 resourcemanager
1 | yarn-daemon.sh start resourcemanager |
日志服务
为了方便查看日志,需要为 10 机器配置日志收集服务,修改 mapred-site.xml, 添加如下配置
1 | <!-- 机器 10 配置jobhistory服务 --> |
1 | <property> |
在 10 机器上将脚本进行分发到其他机器,然后停止并重启集群
1 | bash xsync /opt/module/hadoop-2.7.2/etc/hadoop/ # 注意这里只同步了配置文件的目录 |
在 12 上重启 resourcemanager
1 | yarn-daemon.sh stop resourcemanager |
在 10 上启动日志服务
1 | mr-jobhistory-daemon.sh start historyserver |
再次执行任务
1 | hadoop jar hadoop-mapreduce-examples-2.7.2.jar wordcount /wcinput3 /wcoutput4 |
通过 yarn 的 web 页面查看日志